package com.cevent.${COMMON_MODULE_NAME}.service;

import com.cevent.${COMMON_MODULE_NAME}.domain.${CLASS_NAME_BIG};
import com.cevent.${COMMON_MODULE_NAME}.domain.${CLASS_NAME_BIG}Example;
import com.cevent.${COMMON_MODULE_NAME}.dto.${CLASS_NAME_BIG}ChildrenDto;
import com.cevent.${COMMON_MODULE_NAME}.dto.${CLASS_NAME_BIG}Dto;
import com.cevent.${COMMON_MODULE_NAME}.dto.NodeDto;
import com.cevent.${COMMON_MODULE_NAME}.dto.PageDto;
import com.cevent.${COMMON_MODULE_NAME}.mapper.${CLASS_NAME_BIG}Mapper;
import com.cevent.${COMMON_MODULE_NAME}.mapper.defMapper.${CLASS_NAME_BIG}DefMapper;
import com.cevent.${COMMON_MODULE_NAME}.util.CopyUtil;
import com.cevent.${COMMON_MODULE_NAME}.util.DataUtil;
import com.cevent.${COMMON_MODULE_NAME}.util.UuidUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

<#--生成当前时间-->
<#assign now=.now>
<#--格式化日期-->
<#assign formatDate = now?string("yyyy-MM-dd HH:mm:ss")>

/**
 * @description ${TABLE_NAME_CN}
 * @author cevent
 * @create ${formatDate}
 */
@Service
public class ${CLASS_NAME_BIG}Service {

    private static final Logger LOG= LoggerFactory.getLogger(${CLASS_NAME_BIG}Service.class);

    @Resource
    private ${CLASS_NAME_BIG}Mapper ${CLASS_NAME_SMALL}Mapper;
    @Resource
    private ${CLASS_NAME_BIG}DefMapper ${CLASS_NAME_SMALL}DefMapper;

    //如果需要返回指定类型，则指定List<Dto>，这里因为前端传入的pageDto对象，不做处理也会返回PageDto，所以这里没有return
    public void getList(PageDto pageDto,String domain){

        String domainId="";
        if (!StringUtils.isEmpty(domain)){
            domainId="TODO 请求site配置数据，获取domainId";
        }

        PageHelper.startPage(pageDto.getPage(),pageDto.getSize());
        ${CLASS_NAME_BIG}Example ${CLASS_NAME_SMALL}Example=new ${CLASS_NAME_BIG}Example();
        // ${CLASS_NAME_SMALL}Example.createCriteria().andUniIdEqualTo("1");
        ${CLASS_NAME_BIG}Example.Criteria criteria=${CLASS_NAME_SMALL}Example.createCriteria();
        if(domainId!=""){
            criteria.andDomainIdEqualTo(domainId);
        }
        <#list FIELD_SET_LIST as field>
            <#if field.nameSmallHump=='sort'>
        ${CLASS_NAME_SMALL}Example.setOrderByClause("sort asc");
            </#if>
            <#else>
                <#if field.nameSmallHump=='createTime'>
        ${CLASS_NAME_SMALL}Example.setOrderByClause("create_time desc");
                </#if>
            <#else>
        </#list>

        List<${CLASS_NAME_BIG}> list=${CLASS_NAME_SMALL}Mapper.selectByExample(null);

        //select获取数据后，Pageinfo接收查询结果
        PageInfo<${CLASS_NAME_BIG}> pageInfo=new PageInfo<>(list);

        // List 需要 new ArrayList< entity >
        List<${CLASS_NAME_BIG}Dto> lists= new ArrayList<${CLASS_NAME_BIG}Dto>();
        for (int i = 0, l = list.size(); i < l; i++) {
            ${CLASS_NAME_BIG} ${CLASS_NAME_SMALL}=list.get(i);
            ${CLASS_NAME_BIG}Dto ${CLASS_NAME_SMALL}Dto=new ${CLASS_NAME_BIG}Dto();
            //赋值
            BeanUtils.copyProperties(${CLASS_NAME_SMALL},${CLASS_NAME_SMALL}Dto);
            lists.add(${CLASS_NAME_SMALL}Dto);
        }

        //赋值pageinfo List
        pageDto.setTotal(pageInfo.getTotal());
        pageDto.setList(lists);

        //如果不返回分页数据，则输出lists即可，注意list<dto对象>
        // return pageDto;
    }

    //获取tree结构数据
    public List<${CLASS_NAME_BIG}ChildrenDto> getTree(String domain){
        String dominId="";
        if(!StringUtils.isEmpty(domain)){
            LOG.info("TODO 请求site配置数据，获取domainId: {}",domain);
        }

        //获取分类
        ${CLASS_NAME_BIG}Example example=new ${CLASS_NAME_BIG}Example();
        ${CLASS_NAME_BIG}Example.Criteria criteria=example.createCriteria();
        // criteria.andDomainIdEqualTo(dominId);
        example.setOrderByClause("sort asc");
        List<${CLASS_NAME_BIG}> moduleCategories=${CLASS_NAME_SMALL}Mapper.selectByExample(example);

        //生成children
        List<${CLASS_NAME_BIG}ChildrenDto> childrenDtos=CopyUtil.copyList(moduleCategories, ${CLASS_NAME_BIG}ChildrenDto.class);
        //获取一级分类
        List<${CLASS_NAME_BIG}ChildrenDto> level1=childrenDtos.stream().filter((category)->{
            return category.getParentId().equals("0");
        }).map((child)->{
            child.setChildren(getChildren(child,childrenDtos));
            return child;
        }).sorted((cat1,cat2)->{
            return (cat1.getSort() == null ? 0 : cat1.getSort()) - (cat2.getSort() == null ? 0 : cat2.getSort());
        }).collect(Collectors.toList());

        return level1;
    }

    //递归查询子分类
    private List<${CLASS_NAME_BIG}ChildrenDto> getChildren(${CLASS_NAME_BIG}ChildrenDto childrenDto,List<${CLASS_NAME_BIG}ChildrenDto> childrenDtoList){
        List<${CLASS_NAME_BIG}ChildrenDto> childrens=childrenDtoList.stream().filter(category->{
            return category.getParentId().equals(childrenDto.getUniId());
        }).map((child)->{
            child.setChildren(getChildren(child,childrenDtoList));
            return child;
        }).sorted((cat1,cat2)->{
            //避免空指针异常
            return (cat1.getSort() == null ? 0 : cat1.getSort()) - (cat2.getSort() == null ? 0 : cat2.getSort());
        }).collect(Collectors.toList());

        return childrens;
    }

    public void save(${CLASS_NAME_BIG}Dto ${CLASS_NAME_SMALL}Dto,String domain){
        //isEmpty被弃用，hasText可校验""/" "/null
        if(StringUtils.hasText(${CLASS_NAME_SMALL}Dto.getParentId()) || ${CLASS_NAME_SMALL}Dto.getParentId()==null){
            ${CLASS_NAME_SMALL}Dto.setParentId("0");
        }
        if(!StringUtils.hasText(${CLASS_NAME_SMALL}Dto.getUniId())){
            this.insert(CopyUtil.copy(${CLASS_NAME_SMALL}Dto,${CLASS_NAME_BIG}.class));
        }else{
            //优化，只更新传入的字段
            this.update(CopyUtil.copy(${CLASS_NAME_SMALL}Dto,${CLASS_NAME_BIG}.class));
        }
    }

    private void insert(${CLASS_NAME_BIG} ${CLASS_NAME_SMALL}){
        ${CLASS_NAME_SMALL}.setUniId(UuidUtil.getUuid8());
        Date now=new Date();
        ${CLASS_NAME_SMALL}.setCreateTime(now);
        ${CLASS_NAME_SMALL}.setUpdateTime(now);
        ${CLASS_NAME_SMALL}Mapper.insert(${CLASS_NAME_SMALL});
    }

    private void update(${CLASS_NAME_BIG} ${CLASS_NAME_SMALL}){

        ${CLASS_NAME_SMALL}Mapper.updateByPrimaryKey(${CLASS_NAME_SMALL});
    }

    public ${CLASS_NAME_BIG}Dto detail(String uniId){
        ${CLASS_NAME_BIG} ${CLASS_NAME_SMALL}=new ${CLASS_NAME_BIG}();
        if(uniId != ""){
            ${CLASS_NAME_SMALL}=${CLASS_NAME_SMALL}Mapper.selectByPrimaryKey(uniId);
        }
        return CopyUtil.copy(${CLASS_NAME_SMALL},${CLASS_NAME_BIG}Dto.class);
    }

    public Boolean delete(String uniId,String domian){
        //TODO 先根据id和domain查询是否是当前站点的分类数据
        Integer flag=0;
        if(StringUtils.hasText(uniId)){
            flag=${CLASS_NAME_SMALL}Mapper.deleteByPrimaryKey(uniId);
        }

        return flag>0;
    }

    public List<${CLASS_NAME_BIG}ChildrenDto> saveTree(List<${CLASS_NAME_BIG}ChildrenDto> childrenDtos,String domain){
        String dominId="";
        if(!StringUtils.isEmpty(domain)){
            LOG.info("TODO 请求site配置数据，获取domainId: {}",domain);
        }
        List<${CLASS_NAME_BIG}ChildrenDto> result= DataUtil.flattenChildren(childrenDtos);
        List<${CLASS_NAME_BIG}> ${CLASS_NAME_SMALL}List=CopyUtil.copyList(result,${CLASS_NAME_BIG}.class);
        for (int i = 0, l = ${CLASS_NAME_SMALL}List.size(); i < l; i++) {

            ${CLASS_NAME_BIG} ${CLASS_NAME_SMALL}=${CLASS_NAME_SMALL}List.get(i);
            // ${CLASS_NAME_SMALL}Mapper.updateByPrimaryKeySelective(${CLASS_NAME_SMALL});
            //自定义mapper
            int flag= ${CLASS_NAME_SMALL}DefMapper.${CLASS_NAME_SMALL}TreeDragSave(${CLASS_NAME_SMALL}.getUniId(),${CLASS_NAME_SMALL}.getParentId(),${CLASS_NAME_SMALL}.getSort(),${CLASS_NAME_SMALL}.getLevel());

        }
        return result;
    }

}
